﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
using EPiServer.Core;
using EPiServer.Core.Transfer;
using EPiServer.Framework.DataAnnotations;
using EPiServer.Framework.Serialization;
using EPiServer.PlugIn;
using EPiServer.ServiceLocation;
using EPiServer.Web;
using OpenWaves.EPiServer.CustomProperties;

namespace OpenWaves.EPiServer.GenericListProperty
{

    public interface IGenericListProperty
    {
        object Value { get; }
    }
     

    //
    [EditorHint(PropertyListEditorDescriptor.UIHint)]
    //[PropertyDefinitionTypePlugIn(Description = "Generic List")]
    public class GenericListPropertyBackingType<T> : LongStringProperty<IEnumerable<T>>, IGenericListProperty
        where T : BlockData
    {
        protected override IEnumerable<T> DefaultValue
        {
            get { return Enumerable.Empty<T>(); }
        }

        protected override LongStringProperty<IEnumerable<T>> CreateInstance(IEnumerable<T> value)
        {
            var listInstance = this.CreateListInstance();
            listInstance.Value = value;
            return listInstance;
        }

        protected virtual GenericListPropertyBackingType<T> CreateListInstance()
        {
            return new GenericListPropertyBackingType<T>();
        }

        private IObjectSerializer GetSerializer()
        {
            var objectSerializerFactory = global::EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<IObjectSerializerFactory>();
            var objectSerializer = objectSerializerFactory.GetSerializer(KnownContentTypes.Json);
            return objectSerializer;
        }

        protected override string SerializeValue(IEnumerable<T> value)
        {
            var serializedProperty =
               value.Select(v => v.Property.Where(p => !p.IsStandardProperty()).ToDictionary(p => p.Name, p => p.Value));

            var objectSerializer = this.GetSerializer();
            var result = new StringBuilder();
            objectSerializer.Serialize(new StringWriter(result), serializedProperty);

            //return JsonConvert.SerializeObject(serializedProperty);
            return result.ToString();
            return string.Empty;
        }

        protected override IEnumerable<T> DeserializeValue(string serializedValue)
        {
            try
            {
                //return JsonConvert.DeserializeObject<IEnumerable<T>>(serializedValue);
                var objectSerializer = this.GetSerializer();
                return objectSerializer.Deserialize<IEnumerable<T>>(new StringReader(serializedValue));
            }
            catch //(Exception e)
            {
                return this.DefaultValue;
            }
        }
    }
}